package com.shigen.demo.atguigu;

import cn.hutool.core.util.StrUtil;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 生产者消费者队列
 *
 * @author shigenfu
 * @date 2022/5/22 10:18 下午
 */
class MyResource {

  private volatile boolean FLAG = true;
  private AtomicInteger atomicInteger = new AtomicInteger();

  BlockingQueue<String> blockingQueue = null;

  public MyResource(BlockingQueue<String> blockingQueue) {
    this.blockingQueue = blockingQueue;
    System.out.println(blockingQueue.getClass().getName());
  }

  public void myProd() {
    String data = null;
    boolean resultVal;
    try {
      while (FLAG) {
        data = atomicInteger.getAndIncrement() + "";
        resultVal = blockingQueue.offer(data, 2L, TimeUnit.SECONDS);
        if (resultVal) {
          System.out.println(Thread.currentThread().getName() + " 生产data:" + data);
        } else {
          System.err.println(Thread.currentThread().getName() + " 生产失败data:" + data);
        }
        TimeUnit.SECONDS.sleep(1);
      }
      System.out.println("停止生产了！！");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void myConsumer() {
    String data = null;
    String resultVal;
    try {
      while (FLAG) {
        data = atomicInteger.getAndDecrement() + "";
        resultVal = blockingQueue.poll(2L, TimeUnit.SECONDS);
        if (StrUtil.isNotEmpty(resultVal)) {
          System.out.println(Thread.currentThread().getName() + " 消费data:" + data);
        } else {
          FLAG = false;
          System.err.println(Thread.currentThread().getName() + " 消费data:" + data);
        }
        TimeUnit.SECONDS.sleep(1);
      }
      System.out.println("停止消费了！！");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void stop() {
    this.FLAG = false;
  }
}


public class ProdConsumerBlockQueueDemo {

  public static void main(String[] args) {
    MyResource myResource = new MyResource(new ArrayBlockingQueue<>(4));

   new Thread(() -> {
     myResource.myProd();
   }, "AAA").start();

    new Thread(() -> {
      myResource.myConsumer();
    }, "BBB").start();

    try {
      TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    myResource.stop();

  }
}
